﻿#region (C) Header Region @ 2012
//====================================================
// 文件: DataHelper.cs
// 描述: 
// 路径: Antu.Core\DataAccess\DataHelper.cs
// ******************版本1 ******************
// 人员: 蔡金保    时间 : 2012/11/20 12:36:53
// 注释: 
//====================================================
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data;
using System.Runtime.Serialization;

namespace Antu.Core.DataAccess
{
    /// <summary>
    /// 跟实体类、数据库配合转换(默认只转换string与日期格式,clob等非常规字段请重写方法)只处理string，int，datetime 3类型的转换
    /// 注意：int型插入操作时会默认为0，会导致数据库中的默认设置失效，所以在定义实体类时要将int型指定默认值，不指定默认为0
    /// 注意：该类只处理常规类型（ dateTime，string，int，double，float，bool）不处理如List<>，string[]等类型   ，这种要单独写程序
    /// </summary>
    public class DataHelper
    {
        /// <summary>
        /// 根据dt自动填充实体类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> DataTableToT<T>(DataTable dt) where T : class
        {
            List<T> tlist = new List<T>();
            object obj = FormatterServices.GetUninitializedObject(typeof(T));
            PropertyInfo[] fields = obj.GetType().GetProperties();
            foreach (DataRow dr in dt.Rows)
            {
                obj = FormatterServices.GetUninitializedObject(typeof(T));
                foreach (DataColumn dc in dt.Columns)
                {
                    foreach (PropertyInfo pi in fields)
                    {
                        if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(string) || pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float) || pi.PropertyType == typeof(bool))
                        {
                            if (dc.ColumnName.ToLower() == pi.Name.ToLower())
                            {
                                if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))
                                {
                                    if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
                                    {
                                        pi.SetValue(obj, Convert.ToDateTime(dr[dc.ColumnName].ToString()), null);
                                    }
                                    else
                                    {
                                        pi.SetValue(obj, null, null);
                                    }
                                }
                                else if (pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float))
                                {
                                    if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
                                    {
                                        if (pi.PropertyType == typeof(int))
                                        {
                                            pi.SetValue(obj, Convert.ToInt32(dr[dc.ColumnName].ToString()), null);
                                        }
                                        else if (pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float))
                                        {
                                            pi.SetValue(obj, Convert.ToDouble(dr[dc.ColumnName].ToString()), null);
                                        }
                                    }
                                    else
                                    {
                                        pi.SetValue(obj, 0, null);
                                    }
                                }
                                else
                                {
                                    pi.SetValue(obj, dr[dc.ColumnName].ToString(), null);
                                }
                                continue;
                            }
                        }
                    }
                }
                tlist.Add((T)obj);
            }
            return tlist;
        }
        /// <summary>
        /// 根据dt自动填充实体类，只填充一条
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static T DataTableToTOne<T>(DataTable dt) where T : class
        {
            object obj = FormatterServices.GetUninitializedObject(typeof(T));
            PropertyInfo[] fields = obj.GetType().GetProperties();
            if (dt != null && dt.Rows.Count > 0)
            {
                obj = FormatterServices.GetUninitializedObject(typeof(T));
                foreach (DataColumn dc in dt.Columns)
                {
                    foreach (PropertyInfo pi in fields)
                    {
                        if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(string) || pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float) || pi.PropertyType == typeof(bool))
                        {
                            if (dc.ColumnName.ToLower() == pi.Name.ToLower())
                            {
                                if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))
                                {
                                    if (!string.IsNullOrEmpty(dt.Rows[0][dc.ColumnName].ToString()))
                                    {
                                        pi.SetValue(obj, Convert.ToDateTime(dt.Rows[0][dc.ColumnName].ToString()), null);
                                    }
                                    else
                                    {
                                        pi.SetValue(obj, null, null);
                                    }
                                }
                                else if (pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float))
                                {
                                    if (!string.IsNullOrEmpty(dt.Rows[0][dc.ColumnName].ToString()))
                                    {
                                        if (pi.PropertyType == typeof(int))
                                        {
                                            pi.SetValue(obj, Convert.ToInt32(dt.Rows[0][dc.ColumnName].ToString()), null);
                                        }
                                        else if (pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float))
                                        {
                                            pi.SetValue(obj, Convert.ToDouble(dt.Rows[0][dc.ColumnName].ToString()), null);
                                        }
                                    }
                                    else
                                    {
                                        pi.SetValue(obj, 0, null);
                                    }
                                }
                                else
                                {
                                    pi.SetValue(obj, dt.Rows[0][dc.ColumnName].ToString(), null);
                                }
                                continue;
                            }
                        }
                    }
                }
            }
            return (T)obj;
        }
        /// <summary>
        /// 根据dr自动填充实体类，只填充一条注意：这里的datarow必须有附属的table，不可直接new一个datarow来调用该函数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static T DataTableToTOne<T>(DataRow dr) where T : class
        {
            object obj = FormatterServices.GetUninitializedObject(typeof(T));
            PropertyInfo[] fields = obj.GetType().GetProperties();
            if (dr != null && dr.Table != null && dr.Table.Rows.Count > 0 && dr.ItemArray.Length > 0)
            {
                obj = FormatterServices.GetUninitializedObject(typeof(T));
                foreach (DataColumn dc in dr.Table.Columns)
                {
                    foreach (PropertyInfo pi in fields)
                    {
                        if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(string) || pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float) || pi.PropertyType == typeof(bool))
                        {
                            if (dc.ColumnName.ToLower() == pi.Name.ToLower())
                            {
                                if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))
                                {
                                    if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
                                    {
                                        pi.SetValue(obj, Convert.ToDateTime(dr[dc.ColumnName].ToString()), null);
                                    }
                                    else
                                    {
                                        pi.SetValue(obj, null, null);
                                    }
                                }
                                else if (pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float))
                                {
                                    if (!string.IsNullOrEmpty(dr[dc.ColumnName].ToString()))
                                    {
                                        if (pi.PropertyType == typeof(int))
                                        {
                                            pi.SetValue(obj, Convert.ToInt32(dr[dc.ColumnName].ToString()), null);
                                        }
                                        else if (pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float))
                                        {
                                            pi.SetValue(obj, Convert.ToDouble(dr[dc.ColumnName].ToString()), null);
                                        }
                                    }
                                    else
                                    {
                                        pi.SetValue(obj, 0, null);
                                    }
                                }
                                else
                                {
                                    pi.SetValue(obj, dr[dc.ColumnName].ToString(), null);
                                }
                                continue;
                            }
                        }
                    }
                }
            }
            return (T)obj;
        }
        /// <summary>
        /// 根据实体类生成insert语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tobj"></param>
        /// <returns></returns>
        public static string AddT<T>(T tobj, string tablename) where T : class
        {
            object obj = FormatterServices.GetUninitializedObject(typeof(T));
            PropertyInfo[] fields = obj.GetType().GetProperties();
            string fieldstr = "";
            string valuestr = "";
            foreach (PropertyInfo pi in fields)
            {
                if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(string) || pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float) || pi.PropertyType == typeof(bool))
                {
                    if (pi.GetValue(tobj, null) != null)
                    {
                        if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))
                        {
                            if (!string.IsNullOrEmpty(pi.GetValue(tobj, null).ToString()) && pi.GetValue(tobj, null).ToString() != (DateTime.MinValue.ToString()))
                            {
                                fieldstr += pi.Name.ToLower() + ",";
                                valuestr += "to_date('" + pi.GetValue(tobj, null) + "','yyyy-MM-dd hh24:mi:ss'),";
                            }
                        }
                        else
                        {
                            fieldstr += pi.Name.ToLower() + ",";
                            valuestr += "'" + pi.GetValue(tobj, null) + "',";
                        }
                    }
                }
            }
            fieldstr = fieldstr.TrimEnd(',');
            valuestr = valuestr.TrimEnd(',');
            if (!string.IsNullOrEmpty(fieldstr))
            {
                return "insert into " + tablename + " (" + fieldstr + ")values(" + valuestr + ")";
            }
            return "";
        }
        /// <summary>
        /// 根据实体类生成update语句(注意这里的实体类必须都要先赋值初始化，特别是日期，不然会自动置空)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tobj"></param>
        /// <param name="tablename"></param>
        /// <param name="key">where条件后的字段名，可以多个</param>
        /// <returns></returns>
        public static string UpdateT<T>(T tobj, string tablename, string[] key) where T : class
        {
            object obj = FormatterServices.GetUninitializedObject(typeof(T));
            PropertyInfo[] fields = obj.GetType().GetProperties();
            string fieldstr = "";
            string wherestr = "";
            foreach (PropertyInfo pi in fields)
            {
                if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?) || pi.PropertyType == typeof(string) || pi.PropertyType == typeof(int) || pi.PropertyType == typeof(double) || pi.PropertyType == typeof(float) || pi.PropertyType == typeof(bool))
                {
                    for (int temp = 0; temp < key.Length; temp++)
                    {
                        if (pi.Name.ToLower() == key[temp].ToLower())
                        {

                            wherestr += " and " + pi.Name.ToLower() + "='" + pi.GetValue(tobj, null) + "' ";
                        }
                    }

                    if (pi.PropertyType == typeof(DateTime) || pi.PropertyType == typeof(DateTime?))
                    {
                        if (pi.GetValue(tobj, null) != null && pi.GetValue(tobj, null).ToString() != "" && pi.GetValue(tobj, null).ToString() != (DateTime.MinValue.ToString()))
                        {
                            fieldstr += pi.Name.ToLower() + "=to_date('" + pi.GetValue(tobj, null) + "','yyyy-MM-dd hh24:mi:ss'),";
                        }
                        else
                        {
                            fieldstr += pi.Name.ToLower() + "=null,";
                        }

                    }
                    else
                    {
                        fieldstr += pi.Name.ToLower() + "='" + pi.GetValue(tobj, null) + "',";
                    }
                }
            }
            fieldstr = fieldstr.TrimEnd(',');
            if (!string.IsNullOrEmpty(fieldstr) && !string.IsNullOrEmpty(wherestr))
            {
                return "update " + tablename + " set " + fieldstr + " where 1=1 " + wherestr;
            }
            return "";
        }


    }
}
